/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Bullet几何.h"


#include <ppl.h>
#include "Bullet几何.h"


using namespace std;











S_Bulle平面::S_Bulle平面(const vec4& plane) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理碰撞几何类型::E_碰撞几何_平面;

	m_Shape = new btStaticPlaneShape({ plane.x, plane.y, plane.z }, plane.w);
	//m_Shape = new btBoxShape(btVector3(btScalar(300.), btScalar(3.), btScalar(300.)));
	m_Shape->setMargin(0.01);
}

S_Bulle平面::~S_Bulle平面() {
	delete m_Shape;
}








S_Bullet球体几何体::S_Bullet球体几何体(const float32 半径) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理碰撞几何类型::E_碰撞几何_球体;
	m_重量 = 1.0;

	m_Shape = new btSphereShape(半径);
	m_Shape->setMargin(0.03);
	
}

void S_Bullet球体几何体::f_set质量(float32 v) {
	m_重量 = v;
}





S_Bullet长方体几何体::S_Bullet长方体几何体(const vec3& ckg) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理碰撞几何类型::E_碰撞几何_方体;
	m_重量 = 1.0;

	auto box = vec_abs(ckg);
	//m_Shape = new btBoxShape({ box.x, box.y, box.z });
	m_Shape = new btBoxShape(btVector3(btScalar(box.x), btScalar(box.y), btScalar(box.z)));
	//m_Shape->setMargin(0.3);
	m_Shape->setMargin(0.03);
	
}

void S_Bullet长方体几何体::f_set质量(float32 v) {
	m_重量 = v;
}



S_Bullet凸包几何体::S_Bullet凸包几何体(const S_三角Mesh& v) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理碰撞几何类型::E_碰撞几何_凸壳;
	m_重量 = 1.0;


	uint32 num = v.m_vNum;
	auto* p = v.m_vert;
	
	vector<btScalar> points(num * 3);
	auto* r = points.data();

	Concurrency::parallel_for<uint32>(0, num, [&](uint32 i) {
		r[i * 3 + 0] = p[i].x;
		r[i * 3 + 1] = p[i].y;
		r[i * 3 + 2] = p[i].z;
	});

	/*vector<btVector3> points(num);
	Concurrency::parallel_for<uint32>(0, num, [&](uint32 i) {
		r[i].setValue(p[i].x, p[i].y, p[i].z);
	});*/

	
	btVector3 loc = { 0.0f, 0.0f, 0.0f };
	//m_Shape = new btConvexPointCloudShape(r, num, loc);
	m_Shape = new btConvexHullShape(r, num);

	m_Shape->setMargin(0.03);
	
	/*btVector3 localInertia(0, 0, 0);
	if (isDynamic)
		colShape->calculateLocalInertia(mass, localInertia);

	for (int k = 0; k < ARRAY_SIZE_Y; k++)
	{
		for (int i = 0; i < ARRAY_SIZE_X; i++)
		{
			for (int j = 0; j < ARRAY_SIZE_Z; j++)
			{
				startTransform.setOrigin(btVector3(
					btScalar(2.0 * i + 0.1),
					btScalar(3 + 2.0 * k),
					btScalar(2.0 * j)));

				btRigidBody* body;
				body = createRigidBody(mass, startTransform, colShape);
				//body->setAngularVelocity(btVector3(1,1,1));
			}
		}
	}*/

	//rigidbody is dynamic if and only if mass is non zero, otherwise static
	//bool isDynamic = (m_重量 != 0.f);
	btAssert((!m_Shape || m_Shape->getShapeType() != INVALID_SHAPE_PROXYTYPE));
	//rigidbody is dynamic if and only if mass is non zero, otherwise static
	
}

void S_Bullet凸包几何体::f_set质量(float32 v)
{
	m_重量 = v;
}

S_Bullet圆柱几何体::S_Bullet圆柱几何体(const vec3& ckg, float32 密度) {
	m_Shape = new btCylinderShapeX({ ckg.x, ckg.y, ckg.z });
	m_Shape->setMargin(0.03);
}

void S_Bullet圆柱几何体::f_set质量(float32 v)
{
	m_重量 = v;
}












S_Bullet网格几何体::S_Bullet网格几何体(const S_三角Mesh& v) {
	m_物理引擎枚举 = E_物理引擎::E_物理引擎_Bullet;
	m_Type = E_物理碰撞几何类型::E_碰撞几何_网格;
	m_重量 = 1.0;

	btTriangleIndexVertexArray* meshInterface = new btTriangleIndexVertexArray();

	btIndexedMesh part;

	part.m_vertexBase = (const unsigned char*)v.m_vert;
	part.m_vertexStride = sizeof(btScalar) * 3;
	part.m_numVertices = v.m_vNum;
	part.m_triangleIndexBase = (const unsigned char*)v.m_index;
	part.m_triangleIndexStride = sizeof(uint32) * 3;
	part.m_numTriangles = v.m_iNum;
	part.m_indexType = PHY_INTEGER;

	meshInterface->addIndexedMesh(part, PHY_INTEGER);


	bool useQuantizedAabbCompression = true;
	m_Shape = new btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression);
	m_Shape->setMargin(0.03f);
}

void S_Bullet网格几何体::f_set质量(float32 v)
{
	m_重量 = v;
}













